package com.promesa.util;

import com.promesa.gui.VentanaPrincipal;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.security.GeneralSecurityException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import net.jimmc.jshortcut.JShellLink;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

public class Util {

    public static List<String> obtenerListaNombreArchivosFTP() {
        List<String> listaNombreArchivosFTP = new ArrayList<String>();
        FTPClient client = new FTPClient();
        int reply = 0;
        try {
            final String KEY_FILE = "init.key";
            final String FTP_FILE = "ftp.properties";
            Properties props = new Properties();
            InputStreamReader in = new InputStreamReader(new FileInputStream(FTP_FILE), "UTF-8");
            props.load(in);
            String sFTP = props.getProperty("ftp.server").trim();
            String sUser = CryptoUtils.decrypt(props.getProperty("ftp.user").trim(), new File(KEY_FILE)).toString();
            String sPassword = CryptoUtils.decrypt(props.getProperty("ftp.password").trim(), new File(KEY_FILE)).toString();
            String directorio = props.getProperty("ftp.directorio").trim();
            client.connect(sFTP);
            boolean login = client.login(sUser, sPassword);
            if (login) {
                reply = client.getReplyCode();
                if (FTPReply.isPositiveCompletion(reply)) {
                    client.changeWorkingDirectory(directorio);
                    FTPFile[] archivosFTP = client.listFiles();
                    if (archivosFTP.length > 0) {
                        for (FTPFile arch : archivosFTP) {
                            listaNombreArchivosFTP.add(arch.getName());
                        }
                    }
                } else {
                    client.disconnect();
                }
            }
            in.close();
            client.logout();
            client.disconnect();
        } catch (GeneralSecurityException ex) {
            Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
        return listaNombreArchivosFTP;
    }

    public static boolean validoDescargaCorrecta() {
        boolean descargoCorrectamente = false;
        try {
            final String KEY_FILE = "init.key";
            final String FTP_FILE = "ftp.properties";
            final Properties props = new Properties();
            InputStreamReader in = new InputStreamReader(new FileInputStream(FTP_FILE), "UTF-8");
            props.load(in);
            FTPClient client = new FTPClient();
            String sFTP = props.getProperty("ftp.server").trim();
            String sUser = CryptoUtils.decrypt(props.getProperty("ftp.user").trim(), new File(KEY_FILE));
            String sPassword = CryptoUtils.decrypt(props.getProperty("ftp.password").trim(), new File(KEY_FILE));
            String sLocalDirectorio = props.getProperty("local.directorio").trim();
            SimpleDateFormat formatoDeFecha = new SimpleDateFormat("ddMMyyyy-HHmmss");
            String nombreTemporal = sLocalDirectorio + "\\_proffline_" + formatoDeFecha.format(new Date()) + "_";
            int reply = 0;
            try {
                client.connect(sFTP);
                boolean login = client.login(sUser, sPassword);
                if (login) {
                    reply = client.getReplyCode();
                    if (FTPReply.isPositiveCompletion(reply)) {
                        try {
                            File file = new File(nombreTemporal);
                            if (file.exists()) {
                                file.delete();
                            }
                            FileOutputStream dfile = new FileOutputStream(file);
                            descargoCorrectamente = client.retrieveFile("/proffline", dfile);
                            dfile.close();
                            if (descargoCorrectamente) {
                                // REEMPLAZAMOS
                                File archivoDescargado = new File(nombreTemporal);
                                File nuevaBaseDatos = new File(sLocalDirectorio + "\\proffline");
                                if (nuevaBaseDatos.exists()) {
                                    nuevaBaseDatos.delete();
                                }
                                archivoDescargado.renameTo(nuevaBaseDatos);
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                            descargoCorrectamente = false;
                        }
                    } else {
                        client.disconnect();
                        descargoCorrectamente = false;
                    }
                } else {
                    descargoCorrectamente = false;
                }
                client.logout();
                client.disconnect();
            } catch (IOException ioe) {
                ioe.printStackTrace();
                descargoCorrectamente = false;
            }
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
            descargoCorrectamente = false;
        }
        return descargoCorrectamente;
    }

    public static boolean instalarAplicacion() {
        boolean bandera = true;
        try {
            final String KEY_FILE = "init.key";
            final String FTP_FILE = "ftp.properties";
            final Properties props = new Properties();
            InputStreamReader in = new InputStreamReader(new FileInputStream(FTP_FILE), "UTF-8");
            props.load(in);
            FTPClient client = new FTPClient();
            String sFTP = props.getProperty("ftp.server").trim();
            String sUser = CryptoUtils.decrypt(props.getProperty("ftp.user").trim(), new File(KEY_FILE));
            String sPassword = CryptoUtils.decrypt(props.getProperty("ftp.password").trim(), new File(KEY_FILE));
            String sFtpDirectorio = props.getProperty("ftp.directorio").trim();
            String sLocalDirectorio = props.getProperty("local.directorio").trim();
            int reply = 0;
            String jarFileName = sLocalDirectorio + "\\proffline.jar";
            JShellLink link = new JShellLink();
            link.setFolder(JShellLink.getDirectory("desktop"));
            link.setName("Proffline");
            link.setPath(jarFileName);
            link.save();
            try {
                client.connect(sFTP);
                boolean login = client.login(sUser, sPassword);
                if (login) {
                    reply = client.getReplyCode();
                    if (FTPReply.isPositiveCompletion(reply)) {
                        client.changeWorkingDirectory(sFtpDirectorio);
                        FTPFile[] archivosFTP = client.listFiles();
                        if (archivosFTP.length > 0) {
                            crearCarpeta(sLocalDirectorio);
                            for (FTPFile arch : archivosFTP) {
                                if (arch.isFile()) {
                                    File file = new File(sLocalDirectorio + "\\" + arch.getName());
                                    descargarArchivo(arch, "ftp://" + sUser + ":" + sPassword + "@" + sFTP + sFtpDirectorio + "/" + arch.getName(), file);
//                                    FileOutputStream dfile = new FileOutputStream(file);
//                                    client.retrieveFile(sFtpDirectorio + "/" + arch.getName(), dfile);
//                                    dfile.close();
                                    mostrarMensaje(sLocalDirectorio + "\\" + arch.getName());
                                } else {
                                    System.out.println("-");
                                    client.changeWorkingDirectory("/" + sFtpDirectorio + "/" + arch.getName());
                                    crearCarpeta(sLocalDirectorio + "\\" + arch.getName());
                                    FTPFile[] archivosFTPDirectory = client.listFiles();
                                    if (archivosFTPDirectory.length > 0) {
                                        for (FTPFile arch2 : archivosFTPDirectory) {
                                            File file2 = new File(sLocalDirectorio + "\\" + arch.getName() + "\\" + arch2.getName());
                                            descargarArchivo(arch2, "ftp://" + sUser + ":" + sPassword + "@" + sFTP + sFtpDirectorio + "/" + arch.getName() + "/" + arch2.getName(), file2);
//                                            FileOutputStream dfile2 = new FileOutputStream(file2);
//                                            client.retrieveFile(sFtpDirectorio + "/" + arch.getName() + "/" + arch2.getName(), dfile2);
//                                            dfile2.close();
                                            mostrarMensaje(sLocalDirectorio + "\\" + arch.getName() + "\\" + arch2.getName());
                                        }
                                    }
                                }
                            }
                        }
                    } else {
                        client.disconnect();
                    }
                }
                client.logout();
                client.disconnect();
            } catch (IOException ioe) {
                bandera = false;
                JOptionPane.showMessageDialog(VentanaPrincipal.obtenerInstancia(), ioe.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
            }
            in.close();
        } catch (Exception e) {
            bandera = false;
            JOptionPane.showMessageDialog(VentanaPrincipal.obtenerInstancia(), e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);;
        }
        return bandera;
    }

    public static boolean actualizarAplicacion() {
        boolean bandera = true;
        try {
            final String KEY_FILE = "init.key";
            final String FTP_FILE = "ftp.properties";
            final Properties props = new Properties();
            InputStreamReader in = new InputStreamReader(new FileInputStream(FTP_FILE), "UTF-8");
            props.load(in);
            FTPClient client = new FTPClient();
            String sFTP = props.getProperty("ftp.server").trim();
            String sUser = CryptoUtils.decrypt(props.getProperty("ftp.user").trim(), new File(KEY_FILE));
            String sPassword = CryptoUtils.decrypt(props.getProperty("ftp.password").trim(), new File(KEY_FILE));
            String sFtpDirectorio = props.getProperty("ftp.directorio").trim();
            String sLocalDirectorio = props.getProperty("local.directorio").trim();
            int reply = 0;
            try {
                client.connect(sFTP);
                boolean login = client.login(sUser, sPassword);
                if (login) {
                    reply = client.getReplyCode();
                    if (FTPReply.isPositiveCompletion(reply)) {
                        client.changeWorkingDirectory(sFtpDirectorio);
                        FTPFile[] archivosFTP = client.listFiles();
                        if (archivosFTP.length > 0) {
                            for (FTPFile arch : archivosFTP) {
                                if (("proffline.jar").equals(arch.getName())) {
                                    File file = new File(sLocalDirectorio + "\\" + arch.getName());
                                    FileOutputStream dfile = new FileOutputStream(file);
                                    client.retrieveFile(sFtpDirectorio + "/" + arch.getName(), dfile);
                                    dfile.close();
                                    mostrarMensaje(sLocalDirectorio + "\\" + arch.getName());
                                }
                            }
                        }
                    } else {
                        client.disconnect();
                    }
                }
                client.logout();
                client.disconnect();
            } catch (IOException ioe) {
                bandera = false;
                JOptionPane.showMessageDialog(VentanaPrincipal.obtenerInstancia(), ioe.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
            }
            in.close();
        } catch (Exception e) {
            bandera = false;
            JOptionPane.showMessageDialog(VentanaPrincipal.obtenerInstancia(), e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        }
        return bandera;
    }

    public static boolean instalarAplicacionPersonalizada(List<String> listaNombreArchivosFTP) {
        boolean bandera = true;
        try {
            final String KEY_FILE = "init.key";
            final String FTP_FILE = "ftp.properties";
            final Properties props = new Properties();
            InputStreamReader in = new InputStreamReader(new FileInputStream(FTP_FILE), "UTF-8");
            props.load(in);
            FTPClient client = new FTPClient();
            String sFTP = props.getProperty("ftp.server").trim();
            String sUser = CryptoUtils.decrypt(props.getProperty("ftp.user").trim(), new File(KEY_FILE));
            String sPassword = CryptoUtils.decrypt(props.getProperty("ftp.password").trim(), new File(KEY_FILE));
            String sFtpDirectorio = props.getProperty("ftp.directorio").trim();
            String sLocalDirectorio = props.getProperty("local.directorio").trim();
            int reply = 0;
            try {
                client.connect(sFTP);
                boolean login = client.login(sUser, sPassword);
                if (login) {
                    reply = client.getReplyCode();
                    if (FTPReply.isPositiveCompletion(reply)) {
                        client.changeWorkingDirectory(sFtpDirectorio);
                        FTPFile[] archivosFTP = client.listFiles();
                        if (archivosFTP.length > 0) {
                            for (String nombreArchivosFTP : listaNombreArchivosFTP) {
                                for (FTPFile arch : archivosFTP) {
                                    if (nombreArchivosFTP.equals(arch.getName())) {
                                        if (arch.isFile()) {
                                            File file = new File(sLocalDirectorio + "\\" + arch.getName());
                                            FileOutputStream dfile = new FileOutputStream(file);
                                            client.retrieveFile(sFtpDirectorio + "/" + arch.getName(), dfile);
                                            dfile.close();
                                            mostrarMensaje(sLocalDirectorio + "\\" + arch.getName());
                                        } else {
                                            client.changeWorkingDirectory("/" + sFtpDirectorio + "/" + arch.getName());
                                            FTPFile[] archivosFTPDirectory = client.listFiles();
                                            if (archivosFTPDirectory.length > 0) {
                                                crearCarpeta(sLocalDirectorio + "\\" + arch.getName());
                                                for (FTPFile arch2 : archivosFTPDirectory) {
                                                    File file2 = new File(sLocalDirectorio + "\\" + arch.getName() + "\\" + arch2.getName());
                                                    FileOutputStream dfile2 = new FileOutputStream(file2);
                                                    client.retrieveFile(sFtpDirectorio + "/" + arch.getName() + "/" + arch2.getName(), dfile2);
                                                    dfile2.close();
                                                    mostrarMensaje(sLocalDirectorio + "\\" + arch.getName() + "\\" + arch2.getName());
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    } else {
                        client.disconnect();
                    }
                }
                client.logout();
                client.disconnect();
            } catch (IOException ioe) {
                bandera = false;
                JOptionPane.showMessageDialog(VentanaPrincipal.obtenerInstancia(), ioe.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
            }
            in.close();
        } catch (Exception e) {
            bandera = false;
            JOptionPane.showMessageDialog(VentanaPrincipal.obtenerInstancia(), e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        }
        return bandera;
    }

    private static void crearCarpeta(String rutaCarpeta) {
        File f = new File(rutaCarpeta);
        borrarDirectorio(f);
        File directorio = new File(rutaCarpeta);
        directorio.mkdirs();
    }

    public static void borrarDirectorio(File directorio) {
        File[] ficheros = directorio.listFiles();
        if (ficheros != null) {
            for (int x = 0; x < ficheros.length; x++) {
                if (ficheros[x].isDirectory()) {
                    borrarDirectorio(ficheros[x]);
                }
                ficheros[x].delete();
            }
        }
    }

    private static void mostrarMensaje(String ruta) {
        VentanaPrincipal.obtenerInstancia().agregarArchivoDescargadoCorrectamente(ruta);
    }

    private static void descargarArchivo(FTPFile arch, String sUrl, File localFile) {
        try {
            URL url = new URL(sUrl);
            URLConnection con = url.openConnection();
            BufferedInputStream in = new BufferedInputStream(con.getInputStream());
            System.out.println("Downloading file " + arch.getSize());
            //Downloads the selected file to the C drive
            FileOutputStream out = new FileOutputStream(localFile);
            int i = 0;
            byte[] bytesIn = new byte[1024];
            int longitudArchivo = (int) arch.getSize() / 1024;
            VentanaPrincipal.obtenerInstancia().establecerValoresBarraProgreso(0, longitudArchivo);
            int longitudArchivoParcial = 0;
            while ((i = in.read(bytesIn)) >= 0) {
                out.write(bytesIn, 0, i);
                longitudArchivoParcial += i;
                VentanaPrincipal.obtenerInstancia().establecerValorBarraProgreso(longitudArchivoParcial / 1024);
            }
            out.close();
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
